package com.fate.framework.response;

import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.NotRoleException;
import com.fate.framework.exception.KKException;
import jakarta.validation.ConstraintViolationException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.HandlerMethodValidationException;
import org.springframework.web.servlet.resource.NoResourceFoundException;

/**
 * @author : ten.x
 * @date : 2022-03-16
 */
@Slf4j
@RestControllerAdvice
@ComponentScan(basePackages = {"com.fate"})
public class GlobalExceptionHandler {

  /**
   * get请求中的参数校验
   *
   * @param exception
   * @return
   */
  @ExceptionHandler(ConstraintViolationException.class)
  @ResponseStatus(HttpStatus.BAD_REQUEST)
  public CommonResult<CommonEnum> constraintViolationExceptionHandler(
      ConstraintViolationException exception) {
    log.error("参数异常信息 :", exception);
    StringBuffer message = new StringBuffer();
    exception
        .getConstraintViolations()
        .forEach(
            e -> {
              message.append(e.getMessage()).append(",");
            });
    String result = message.toString();
    return CommonResult.fail(result.substring(0, result.length() - 1));
  }

  @ExceptionHandler(HandlerMethodValidationException.class)
  @ResponseStatus(HttpStatus.BAD_REQUEST)
  public CommonResult<CommonEnum> handlerMethodValidationExceptionHandler(
      HandlerMethodValidationException exception) {
    log.error("参数异常信息 :", exception);
    StringBuffer message = new StringBuffer();
    exception
        .getAllValidationResults()
        .forEach(
            error -> {
              message.append(error.getResolvableErrors()).append(",");
            });
    String result = message.toString();
    return CommonResult.fail(result.substring(0, result.length() - 1));
  }

  /**
   * form-data格式的参数校验
   *
   * @param exception
   * @return
   */
  @ExceptionHandler(BindException.class)
  @ResponseStatus(HttpStatus.BAD_REQUEST)
  public CommonResult<CommonEnum> bindExceptionHandler(BindException exception) {
    log.error("参数异常信息 :", exception);
    StringBuffer message = new StringBuffer();
    exception
        .getAllErrors()
        .forEach(
            error -> {
              message.append(error.getDefaultMessage()).append(",");
            });
    String result = message.toString();
    return CommonResult.fail(result.substring(0, result.length() - 1));
  }

  @ExceptionHandler({KKException.class})
  public CommonResult<CommonEnum> RRExceptionHandler(KKException exception) {
    log.error("RR异常捕获 :", exception);
    return CommonResult.fail(exception.getCode(), exception.getMessage());
  }

  @ExceptionHandler({HttpRequestMethodNotSupportedException.class})
  public CommonResult<CommonEnum> RRExceptionHandler(
      HttpRequestMethodNotSupportedException exception) {
    log.error("请求方式异常捕获 :", exception);
    return CommonResult.fail(500, exception.getMessage());
  }

  @ExceptionHandler({NotLoginException.class})
  public CommonResult<CommonEnum> NotLoginExceptionHandler(NotLoginException exception) {
    log.error("登录异常捕获 :", exception);
    return CommonResult.fail(exception.getCode(), exception.getMessage());
  }

  @ExceptionHandler({NotRoleException.class})
  public CommonResult<CommonEnum> NotRoleExceptionHandler(NotRoleException exception) {
    log.error("角色权限异常捕获 :", exception);
    return CommonResult.fail(exception.getCode(), exception.getMessage());
  }

  @ExceptionHandler({NoResourceFoundException.class})
  public CommonResult<CommonEnum> NoResourceFoundExceptionHandler(
      NoResourceFoundException exception) {
    log.error("登录异常捕获 :", exception);
    return CommonResult.fail(404, exception.getMessage());
  }

  /**
   * json格式的参数校验
   *
   * @param exception
   * @return
   */
  @ResponseBody
  @ExceptionHandler(MethodArgumentNotValidException.class)
  public CommonResult<CommonEnum> MethodArgumentNotValidExceptionHandler(
      MethodArgumentNotValidException exception) {
    log.error("参数异常信息：", exception);
    StringBuffer message = new StringBuffer();
    exception
        .getBindingResult()
        .getAllErrors()
        .forEach(
            (error) -> {
              String errorMessage = error.getDefaultMessage();
              message.append(errorMessage).append(",");
            });
    String result = message.toString();
    return CommonResult.fail(400, result.substring(0, result.length() - 1));
  }

  /**
   * 兜底的一个异常处理
   *
   * @param exception
   * @return
   */
  @ExceptionHandler(Exception.class)
  @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
  public CommonResult<CommonEnum> excepitonHandler(Exception exception) {
    log.error("服务器异常 :", exception);
    return CommonResult.fail("服务器开小差了,请稍后重试!");
  }
}
